home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume25 / genmake / part01 next >
Encoding:
Text File  |  1991-11-06  |  29.2 KB  |  1,475 lines

  1. Newsgroups: comp.sources.misc
  2. From: kyle@nick.csh.rit.edu (Kyle Saunders)
  3. Subject:  v25i034:  genmake - automatically generate a Makefile, Part01/01
  4. Message-ID: <1991Nov6.050248.8175@sparky.imd.sterling.com>
  5. X-Md4-Signature: ef032e1252406a3c250292a3997eece6
  6. Date: Wed, 6 Nov 1991 05:02:48 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: kyle@nick.csh.rit.edu (Kyle Saunders)
  10. Posting-number: Volume 25, Issue 34
  11. Archive-name: genmake/part01
  12. Environment: BSD
  13.  
  14. This is genmake, version 1.03.  As the name implies, it will 
  15. automatically generate a Makefile for a single target.  The 
  16. only supported language is K&R C.  Basically, you run genmake 
  17. in the directory of your project.  Genmake will grind away and 
  18. produce a Makefile.
  19.  
  20. Genmake has the following options:
  21.  
  22.     -v    - prints version info
  23.  
  24.     -i    - interactive prompt to include a file when it
  25.           contains routines that are not used
  26.  
  27.     -e    - exhaustive analysis.  Basically, will check
  28.           functional dependencies, and report if all
  29.           functions in a file are never used.  Takes quite
  30.           a bit longer to run.
  31.  
  32. kyle@nick.csh.rit.edu
  33. -------
  34. # This is a shell archive.  Save it in a file, remove anything before
  35. # this line, and then unpack it by entering "sh file".  Note, it may
  36. # create directories; files and directories will be owned by you and
  37. # have default permissions.
  38. #
  39. # This archive contains:
  40. #
  41. #    README
  42. #    Makefile
  43. #    consts.h
  44. #    err.h
  45. #    opts.h
  46. #    types.h
  47. #    version.h
  48. #    build.c
  49. #    cpp.c
  50. #    genmake.c
  51. #    makef.c
  52. #    nodes.c
  53. #    parse.c
  54. #    print_deps.c
  55. #    valid.c
  56. #
  57. echo x - README
  58. sed 's/^X//' >README << 'END-of-README'
  59. X
  60. X    This is genmake, version 1.03.  As the name implies, it will
  61. Xautomatically generate a Makefile for a single target.  The only supported
  62. Xlanguage is K&R C.
  63. X
  64. X    Basically, you run genmake in the directory of your project.  Genmake
  65. Xwill grind away and produce a Makefile.
  66. X
  67. X    Genmake has the following options:
  68. X
  69. X    -v        - prints version info
  70. X
  71. X    -i        - interactive prompt to include a file when it
  72. X              contains routines that are not used
  73. X
  74. X    -e        - exhaustive analysis.  Basically, will check
  75. X              functional dependencies, and report if all
  76. X              functions in a file are never used.  Takes quite
  77. X              a bit longer to run.
  78. X
  79. X
  80. X    Genmake 1.03 is (c)1990, 1991 by Kyle Saunders, All Rights Reserved
  81. X                     kyle@nick.csh.rit.edu
  82. X                     kxs5829@ultb.isc.rit.edu
  83. X
  84. X    This program is Freely Distributable
  85. X
  86. END-of-README
  87. echo x - Makefile
  88. sed 's/^X//' >Makefile << 'END-of-Makefile'
  89. X#Genmake v1.03  10/30/91  Copyright(c) 1990, 1991 by Kyle Saunders
  90. XCC= gcc
  91. XCOPTS= -O
  92. XOFILES= \
  93. X    parse.o\
  94. X    genmake.o\
  95. X    nodes.o\
  96. X    build.o\
  97. X    print_deps.o\
  98. X    valid.o\
  99. X    makef.o\
  100. X    cpp.o
  101. X#
  102. Xgenmake:    $(OFILES)
  103. X        $(CC) $(COPTS) -o genmake $(OFILES)
  104. X
  105. Xtypes.h:    \
  106. X        consts.h\
  107. X        version.h
  108. X        touch types.h
  109. X
  110. Xparse.o:    types.h\
  111. X        parse.c
  112. X        $(CC) $(COPTS) -c parse.c
  113. X
  114. Xgenmake.o:    types.h\
  115. X        genmake.c\
  116. X        opts.h\
  117. X        err.h
  118. X        $(CC) $(COPTS) -c genmake.c
  119. X
  120. Xnodes.o:    types.h\
  121. X        nodes.c
  122. X        $(CC) $(COPTS) -c nodes.c
  123. X
  124. Xbuild.o:    types.h\
  125. X        build.c
  126. X        $(CC) $(COPTS) -c build.c
  127. X
  128. Xprint_deps.o:    types.h\
  129. X        print_deps.c
  130. X        $(CC) $(COPTS) -c print_deps.c
  131. X
  132. Xvalid.o:    types.h\
  133. X        valid.c
  134. X        $(CC) $(COPTS) -c valid.c
  135. X
  136. Xconsts.h:    
  137. X        touch consts.h
  138. X
  139. Xopts.h:    
  140. X        touch opts.h
  141. X
  142. Xmakef.o:    types.h\
  143. X        makef.c
  144. X        $(CC) $(COPTS) -c makef.c
  145. X
  146. Xerr.h:    
  147. X        touch err.h
  148. X
  149. Xversion.h:    
  150. X        touch version.h
  151. X
  152. Xcpp.o:    types.h\
  153. X        cpp.c
  154. X        $(CC) $(COPTS) -c cpp.c
  155. X
  156. END-of-Makefile
  157. echo x - consts.h
  158. sed 's/^X//' >consts.h << 'END-of-consts.h'
  159. X/* consts.h */
  160. X
  161. X#define    CSOURCE    1
  162. X#define CHEADER    2
  163. X
  164. X#define BUFSIZE    512
  165. END-of-consts.h
  166. echo x - err.h
  167. sed 's/^X//' >err.h << 'END-of-err.h'
  168. X/* err.h */
  169. X
  170. X#define ERRFINDMAIN    1
  171. X#define ERRBUILDDEP    2
  172. X#define ERRCREATEMF    3
  173. X#define ERROPTION    4
  174. END-of-err.h
  175. echo x - opts.h
  176. sed 's/^X//' >opts.h << 'END-of-opts.h'
  177. X/* opts.h */
  178. X
  179. X#define VERSION        'v'
  180. X#define VERBATIM    'V'
  181. X#define EXHAUSTIVE    'e'
  182. X#define INTERACT    'i'
  183. X#define HELP        'h'
  184. END-of-opts.h
  185. echo x - types.h
  186. sed 's/^X//' >types.h << 'END-of-types.h'
  187. X/* types.h */
  188. X
  189. X#include "consts.h"
  190. X#include "version.h"
  191. X
  192. Xextern int    errno;
  193. X
  194. Xtypedef struct file_node {
  195. X    char            *name;        /* file name */
  196. X    struct file_node    *next;
  197. X} FNODE;
  198. X
  199. Xtypedef struct depend_node {
  200. X    char            *name;        /* file name */
  201. X    FNODE            *dlist;        /* list of files that depend
  202. X                           on this one */
  203. X    int            use_it;
  204. X    struct depend_node    *next;
  205. X} DNODE;
  206. X
  207. Xtypedef struct opt_node {
  208. X    int            version;
  209. X    int            verbatim;
  210. X    int            exhaustive;
  211. X    int            interactive;
  212. X} OPTS;
  213. X
  214. Xtypedef struct cpp_node {
  215. X    int            expr_val;
  216. X    int            in_else;
  217. X    struct cpp_node        *next;
  218. X} CPPN;
  219. X
  220. Xtypedef struct sym_ent {
  221. X    char            *name;
  222. X    struct sym_ent        *next;
  223. X} SYMENT;
  224. X
  225. END-of-types.h
  226. echo x - version.h
  227. sed 's/^X//' >version.h << 'END-of-version.h'
  228. X/* version.h */
  229. X
  230. X#define BANNER    "Genmake v1.03  10/30/91  Copyright(c) 1990, 1991 by Kyle Saunders"
  231. END-of-version.h
  232. echo x - build.c
  233. sed 's/^X//' >build.c << 'END-of-build.c'
  234. X/* build.c */
  235. X
  236. X#include <stdio.h>
  237. X#include <sys/types.h>
  238. X#include <sys/dir.h>
  239. X#include "types.h"
  240. X
  241. XDNODE     *add_dep_node();
  242. XFNODE    *add_file_node();
  243. X
  244. X/* goes through the current directory build the dep list for each file */
  245. X
  246. Xbuild_depends(make_list,opts,mname)
  247. XDNODE        **make_list;
  248. XOPTS        *opts;
  249. Xchar        *mname;
  250. X{
  251. X    DIR        *dirp;
  252. X    struct direct    *dp;
  253. X    DNODE        *new;
  254. X    int        is_dep;
  255. X    char        ask[BUFSIZE];
  256. X
  257. X    if ((dirp = opendir(".")) == NULL) {
  258. X        fprintf(stderr,"build_depends(): can't open directory\n");
  259. X        return(0);
  260. X    }
  261. X    /* for each file in the directory */
  262. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  263. X        /* is it a recognisable source file */
  264. X        if (!valid_source_file(dp->d_name))
  265. X            continue;
  266. X        if ((new = add_dep_node(make_list,dp->d_name)) == NULL) {
  267. X            closedir(dirp);
  268. X            return(0);
  269. X        }
  270. X        /* a file depends on itself */
  271. X        add_file_node(new,dp->d_name);
  272. X        /* create the dependency list for the current file */
  273. X        if ((is_dep = build_dep_list(new,opts)) == 0) {
  274. X            closedir(dirp);
  275. X            return(0);
  276. X        }
  277. X        if (opts->exhaustive == 1 && is_dep == 1 && strcmp(new->name,mname)) {
  278. X            fprintf(stderr,"Warning:  no one else uses file %s\n",new->name);
  279. X            if (opts->interactive) {
  280. X                printf("Include file in Makefile(Y/N)? ");
  281. X                gets(ask);
  282. X                if (ask[0] != 'Y' && ask[0] != 'y')
  283. X                    new->use_it = 0;
  284. X            }
  285. X            else
  286. X                new->use_it = 0;
  287. X        }
  288. X    }
  289. X    closedir(dirp);
  290. X    return(1);
  291. X}
  292. X
  293. Xbuild_dep_list(dnode,opts)
  294. XDNODE        *dnode;
  295. XOPTS        *opts;
  296. X{
  297. X    FILE        *fp;
  298. X    int        count = 0;
  299. X    int        cp = 0;
  300. X    int        stype;
  301. X    int        cont;
  302. X    char        buf[BUFSIZE];
  303. X    char        func_name[BUFSIZE];
  304. X    int        aok;
  305. X    int        is_dep = 0;
  306. X    CPPN        **cpp_stack;
  307. X    SYMENT        **symtab;
  308. X
  309. X    stype = valid_source_file(dnode->name);    
  310. X    if (opts->exhaustive == 0 && stype == CSOURCE)
  311. X        return(1);
  312. X    if ((fp = fopen(dnode->name,"r")) == NULL) {
  313. X        fprintf(stderr,"build_dep_list: can't open %s\n",dnode->name);
  314. X        return(0);
  315. X    }
  316. X    cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
  317. X    *cpp_stack = NULL;
  318. X    symtab = (SYMENT **)malloc(sizeof(SYMENT *));
  319. X    *symtab = NULL;
  320. X    buf[0] = NULL;
  321. X    func_name[0] = NULL;
  322. X    /* forever */
  323. X    for (;;) {
  324. X        cont = 1;
  325. X        switch (stype) {
  326. X            /* get the next function definition */    
  327. X            case CSOURCE:    cont = parse_file(fp,func_name,&count,buf,&cp,cpp_stack,symtab);
  328. X                    break;
  329. X            default:    ;
  330. X        }
  331. X        /* if we are done with the file, stop */
  332. X        if (!cont)
  333. X            break;
  334. X        /* add the dependencies */
  335. X        if ((aok = depend_on_it(dnode,func_name)) == 0) {
  336. X            cpp_rel(cpp_stack,symtab);
  337. X            fclose(fp);
  338. X            return(0);
  339. X        }
  340. X        if (aok == 2)
  341. X            is_dep = 1;
  342. X        if (stype == CHEADER)
  343. X            break;
  344. X    }
  345. X    cpp_rel(cpp_stack,symtab);
  346. X    fclose(fp);
  347. X    return(is_dep+1);
  348. X}
  349. X
  350. Xdepend_on_it(dnode,func_name)
  351. XDNODE        *dnode;
  352. Xchar        *func_name;
  353. X{
  354. X    DIR        *dirp;
  355. X    struct direct    *dp;
  356. X    int        stype;
  357. X    int        aok;
  358. X    int        is_dep = 0;
  359. X
  360. X#ifdef DEBUG
  361. X    printf("depend_on_it():  dnode->name= '%s'\nfunc_name= '%s'\n",dnode->name,func_name);
  362. X#endif
  363. X    stype = valid_source_file(dnode->name);    
  364. X    if ((dirp = opendir(".")) == NULL) {
  365. X        fprintf(stderr,"depend_on_it():  Can't open directory\n");
  366. X        return(0);
  367. X    }
  368. X    /* for each file in the directory */
  369. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  370. X        if (!valid_source_file(dp->d_name) || in_file_list(dnode,dp->d_name))
  371. X            continue;
  372. X        switch (stype) {
  373. X            case CSOURCE:    aok = depends(dp->d_name,func_name);
  374. X                    break;
  375. X            case CHEADER:    aok = hdepends(dp->d_name,dnode->name);
  376. X                    break;
  377. X        }
  378. X        /* if we found a dependency, add the current file to list */
  379. X        if (aok) {
  380. X            is_dep = 1;
  381. X            if (add_file_node(dnode,dp->d_name) == NULL) {
  382. X                closedir(dirp);
  383. X                return(0);
  384. X            }
  385. X        }
  386. X    }
  387. X    closedir(dirp);
  388. X    return(is_dep+1);
  389. X}
  390. END-of-build.c
  391. echo x - cpp.c
  392. sed 's/^X//' >cpp.c << 'END-of-cpp.c'
  393. X/* cpp.c */
  394. X
  395. X#include <stdio.h>
  396. X#include "types.h"
  397. X
  398. X/* quick hack to get a cpp front end going */
  399. X
  400. Xcpp_parse(buf,cpp_stack,symtab)
  401. Xchar        *buf;
  402. XCPPN        **cpp_stack;
  403. XSYMENT        **symtab;
  404. X{
  405. X    char        tok[BUFSIZE];
  406. X    char        tok2[BUFSIZE];
  407. X    int        cp = 0;
  408. X
  409. X    if (buf[0] != '#')
  410. X        return(0);
  411. X    if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  412. X        return(0);
  413. X    if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  414. X        return(0);
  415. X    if (!strcmp("define",tok) && cpp_useline(cpp_stack)) {
  416. X        if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  417. X            return(0);
  418. X        add_sym(symtab,tok);
  419. X    }
  420. X    else if (!strcmp("undef",tok) && cpp_useline(cpp_stack)) {
  421. X        if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  422. X            return(0);
  423. X        del_sym(symtab,tok);
  424. X    }
  425. X    else if (!strcmp("ifdef",tok) && cpp_useline(cpp_stack)) {
  426. X#ifdef DEBUG
  427. X        printf("#ifdef\n");
  428. X#endif
  429. X        if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  430. X            return(0);
  431. X        if (find_sym(symtab,tok))
  432. X            push_if(cpp_stack,1);
  433. X        else
  434. X            push_if(cpp_stack,0);
  435. X    }
  436. X    else if (!strcmp("ifndef",tok) && cpp_useline(cpp_stack)) {
  437. X#ifdef DEBUG
  438. X        printf("#ifndef\n");
  439. X#endif
  440. X        if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  441. X            return(0);
  442. X        if (!find_sym(symtab,tok))
  443. X            push_if(cpp_stack,1);
  444. X        else
  445. X            push_if(cpp_stack,0);
  446. X    }
  447. X    else if (!strcmp("if",tok) && cpp_useline(cpp_stack)) {
  448. X#ifdef DEBUG
  449. X        printf("#if\n");
  450. X#endif
  451. X        /* fprintf(stderr,"Warning:  #if not supported\n"); */
  452. X        push_if(cpp_stack,1);
  453. X    }
  454. X    else if (!strcmp("else",tok)) {
  455. X#ifdef DEBUG
  456. X        printf("#else\n");
  457. X#endif
  458. X        set_else(cpp_stack);
  459. X    }
  460. X    else if (!strcmp("endif",tok)) {
  461. X#ifdef DEBUG
  462. X        printf("#endif\n");
  463. X#endif
  464. X        pop_if(cpp_stack);
  465. X    }
  466. X    else if (!strcmp("include",tok) && cpp_useline(cpp_stack)) {
  467. X        if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  468. X            return(0);
  469. X        if (tok[0] == '<') {
  470. X            char    itok[BUFSIZE];
  471. X
  472. X            itok[0] = '\0';
  473. X            if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  474. X                return(0);
  475. X            while (tok[0] != '>') {
  476. X                strcat(itok,tok);
  477. X                if ((cp = gettok(NULL,buf,tok,cp,NULL,NULL)) < 0)
  478. X                    return(0);
  479. X            }
  480. X            sprintf(tok2,"/usr/include/%s",itok);
  481. X            if (!cpp_include(cpp_stack,symtab,tok2))
  482. X                return(-1);
  483. X        } else if (tok[0] == '\"') {
  484. X            int i;
  485. X            
  486. X            for (i = 1; tok[i] != '\"' && tok[i] != NULL; i++)
  487. X                tok2[i-1] = tok[i];
  488. X            tok2[i-1] = NULL;
  489. X            if (!cpp_include(cpp_stack,symtab,tok2))
  490. X                return(-1);
  491. X        }
  492. X    }
  493. X    return(1);
  494. X}
  495. X
  496. Xcpp_useline(cpp_stack)
  497. XCPPN        **cpp_stack;
  498. X{
  499. X    CPPN        *cur;
  500. X
  501. X    if (*cpp_stack == NULL) {
  502. X        return(1);
  503. X    }
  504. X    cur = *cpp_stack;
  505. X    if (cur->expr_val != 0 && cur->in_else == 0) {
  506. X        return(1);
  507. X    }
  508. X    else if (cur->expr_val == 0 && cur->in_else != 0) {
  509. X        return(1);
  510. X    }
  511. X    else {
  512. X        return(0);
  513. X    }
  514. X}
  515. X
  516. Xcpp_rel(cpp_stack,symtab)
  517. XCPPN        **cpp_stack;
  518. XSYMENT        **symtab;
  519. X{
  520. X    CPPN    *cur;
  521. X    CPPN    *next;
  522. X    SYMENT    *scur;
  523. X    SYMENT    *snext;
  524. X
  525. X    cur = *cpp_stack;
  526. X    while (cur != NULL) {
  527. X        next = cur->next;
  528. X        free(cur);
  529. X        cur = next;
  530. X    }    
  531. X    free(cpp_stack);
  532. X    scur = *symtab;
  533. X    while (scur != NULL) {
  534. X        snext = scur->next;
  535. X        free(scur->name);
  536. X        free(scur);
  537. X        scur = snext;
  538. X    }
  539. X    free(symtab);
  540. X}
  541. X
  542. Xadd_sym(symtab,name)
  543. XSYMENT        **symtab;
  544. Xchar        *name;
  545. X{
  546. X    SYMENT        *cur;
  547. X    SYMENT        *prev;
  548. X    SYMENT        *new;
  549. X
  550. X    if (find_sym(symtab,name) != NULL)
  551. X        return(1);
  552. X    prev = NULL;
  553. X    cur = *symtab;
  554. X    while (cur != NULL) {
  555. X        prev = cur;
  556. X        if (!strcmp(cur->name,name))
  557. X            break;
  558. X        cur = cur->next;
  559. X    }
  560. X    if (cur != NULL)
  561. X        return(1);
  562. X    new = (SYMENT *)malloc(sizeof(SYMENT));
  563. X    new->name = (char *)malloc(strlen(name)+1);
  564. X    strcpy(new->name,name);
  565. X    new->next = NULL;
  566. X    if (prev == NULL)
  567. X        *symtab = new;
  568. X    else
  569. X        prev->next = new;
  570. X    return(1);
  571. X}
  572. X
  573. Xdel_sym(symtab,name)
  574. XSYMENT        **symtab;
  575. Xchar        *name;
  576. X{
  577. X    SYMENT        *cur;
  578. X    SYMENT        *prev;
  579. X
  580. X    prev = NULL;
  581. X    cur = *symtab;
  582. X    while (cur != NULL) {
  583. X        if (!strcmp(cur->name,name))
  584. X            break;
  585. X        prev = cur;
  586. X        cur = cur->next;
  587. X    }
  588. X    if (cur == NULL)
  589. X        return(0);
  590. X    if (prev == NULL) {
  591. X        free(cur->name);
  592. X        free(cur);
  593. X        *symtab = NULL;
  594. X    }
  595. X    else {
  596. X        prev->next = cur->next;
  597. X        free(cur->name);
  598. X        free(cur);
  599. X    }
  600. X    return(1);
  601. X}
  602. X
  603. Xfind_sym(symtab,name)
  604. XSYMENT        **symtab;
  605. Xchar        *name;
  606. X{
  607. X    SYMENT        *cur;
  608. X
  609. X    cur = *symtab;
  610. X    while (cur != NULL) {
  611. X#ifdef DEBUG
  612. X        printf("cur->name = '%s'\n",cur->name);
  613. X#endif
  614. X        if (!strcmp(cur->name,name))
  615. X            break;
  616. X        cur = cur->next;
  617. X    }
  618. X    if (cur != NULL)
  619. X        return(1);
  620. X    return(0);
  621. X}
  622. X
  623. Xpush_if(cpp_stack,val)
  624. XCPPN        **cpp_stack;
  625. Xint        val;
  626. X{
  627. X    CPPN        *new;
  628. X
  629. X    new = (CPPN *)malloc(sizeof(CPPN));
  630. X    new->expr_val = val;
  631. X    new->in_else = 0;
  632. X    new->next = *cpp_stack;
  633. X    *cpp_stack = new;
  634. X}
  635. X
  636. Xset_else(cpp_stack)
  637. XCPPN        **cpp_stack;
  638. X{
  639. X    CPPN        *cur;
  640. X
  641. X    cur = *cpp_stack;
  642. X    if (cur == NULL) {
  643. X/*
  644. X        fprintf(stderr,"#else without matching #if[[n]def]\n");
  645. X*/
  646. X        return;
  647. X    }
  648. X    cur->in_else = 1;
  649. X}
  650. X
  651. Xpop_if(cpp_stack)
  652. XCPPN        **cpp_stack;
  653. X{
  654. X    CPPN        *next;
  655. X    CPPN        *cur;
  656. X
  657. X    cur = *cpp_stack;
  658. X    if (cur == NULL) {
  659. X/*
  660. X        fprintf(stderr,"#endif without matching #if[[n]def]\n");
  661. X*/
  662. X        return;
  663. X    }
  664. X    next = cur->next;
  665. X    free(cur);
  666. X    *cpp_stack = next;
  667. X}
  668. X
  669. Xcpp_include(cpp_stack,symtab,name)
  670. XCPPN        **cpp_stack;
  671. XSYMENT        **symtab;
  672. Xchar        *name;
  673. X{
  674. X    char        buf[BUFSIZE];
  675. X    char        tok[BUFSIZE];
  676. X    int        cp;
  677. X    FILE        *fp;
  678. X
  679. X#ifdef DEBUG
  680. X    printf("#include file = '%s'\n",name);
  681. X#endif
  682. X    if ((fp = fopen(name,"r")) == NULL) {
  683. X        fprintf(stderr,"cpp_include():  can't open file '%s'\n",name);
  684. X        return(0);
  685. X    }
  686. X    buf[0] = NULL;
  687. X    cp = 0;
  688. X    while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0)
  689. X        ;
  690. X#ifdef DEBUG
  691. X    printf("ending #include file = '%s'\n",name);
  692. X#endif
  693. X    fclose(fp);
  694. X    return(1);
  695. X}
  696. END-of-cpp.c
  697. echo x - genmake.c
  698. sed 's/^X//' >genmake.c << 'END-of-genmake.c'
  699. X/* genmake.c */
  700. X
  701. X#include <stdio.h>
  702. X#include "opts.h"
  703. X#include "types.h"
  704. X#include "err.h"
  705. X
  706. Xmain(argc,argv)
  707. Xint        argc;
  708. Xchar        *argv[];
  709. X{
  710. X    DNODE        **make_list;
  711. X    OPTS        *opts;
  712. X    char        mname[BUFSIZE];
  713. X
  714. X    opts = (OPTS *)malloc(sizeof(OPTS));
  715. X    parse_options(argc,argv,opts);
  716. X    make_list = (DNODE **)malloc(sizeof(DNODE *));
  717. X    *make_list = NULL;
  718. X    if (!find_main_target(opts,mname)) {
  719. X        free(opts);
  720. X        free_list(make_list);
  721. X        exit(ERRFINDMAIN);
  722. X    }
  723. X    printf("main():  %s\n",mname);
  724. X    if (build_depends(make_list,opts,mname) == 0) {
  725. X        free(opts);
  726. X        free_list(make_list);
  727. X        exit(ERRBUILDDEP);
  728. X    }
  729. X    if (!make_file(make_list,opts,mname)) {
  730. X        free(opts);
  731. X        free_list(make_list);
  732. X        exit(ERRCREATEMF);
  733. X    }
  734. X    free(opts);
  735. X    free_list(make_list);
  736. X    return(0);
  737. X}
  738. X
  739. Xparse_options(argc,argv,opts)
  740. Xint        argc;
  741. Xchar        *argv[];
  742. XOPTS        *opts;
  743. X{
  744. X    int        argn;
  745. X
  746. X    opts->verbatim = 0;
  747. X    opts->exhaustive = 0;
  748. X    opts->interactive = 0;
  749. X    for (argn = 1; argn < argc; argn++) {
  750. X        if (argv[argn][0] == '-') {
  751. X            switch (argv[argn][1]) {
  752. X                case VERSION:    credits();
  753. X                        break;
  754. X                case HELP:    help();
  755. X                        free(opts);
  756. X                        exit(0);
  757. X                        break;
  758. X                case VERBATIM:    opts->verbatim = 1;
  759. X                        break;
  760. X                case EXHAUSTIVE:opts->exhaustive = 1;
  761. X                        break;
  762. X                case INTERACT:    opts->interactive = 1;
  763. X                        break;
  764. X                default:    option_error(argv[argn],opts);
  765. X                        break;
  766. X            }
  767. X        }
  768. X    }
  769. X}
  770. X
  771. Xoption_error(o,opts)
  772. Xchar        *o;
  773. XOPTS        *opts;
  774. X{
  775. X    fprintf(stderr,"genmake:  unknown option '%c'\n",o[1]);
  776. X    help();
  777. X    free(opts);
  778. X    exit(ERROPTION);
  779. X}
  780. X
  781. Xcredits()
  782. X{
  783. X    printf("%s\n",BANNER);
  784. X}
  785. X
  786. Xhelp()
  787. X{
  788. X    printf("Usage:  genmake [-v] [-i] [-e]\n");
  789. X}
  790. X
  791. END-of-genmake.c
  792. echo x - makef.c
  793. sed 's/^X//' >makef.c << 'END-of-makef.c'
  794. X/* makef.c */
  795. X
  796. X#include <stdio.h>
  797. X#include <sys/types.h>
  798. X#include <sys/dir.h>
  799. X#include "types.h"
  800. X
  801. XDNODE        *last_node();
  802. XDNODE        *find_dep();
  803. X
  804. Xmake_file(make_list,opts,mname)
  805. XDNODE        **make_list;
  806. XOPTS        *opts;
  807. Xchar        *mname;
  808. X{
  809. X    FILE        *fp;
  810. X    DNODE        *out;
  811. X    DNODE        *in;
  812. X    DNODE        *last;
  813. X    int        count;
  814. X    int        type;
  815. X    char        name[BUFSIZE];
  816. X
  817. X    if ((fp = fopen("Makefile","w")) == NULL) {
  818. X        fprintf(stderr,"make_file(): can't open Makefile for writing\n");
  819. X        return(0);
  820. X    }
  821. X    if (!macros(make_list,fp,opts,mname)) {
  822. X        fclose(fp);
  823. X        return(0);
  824. X    }
  825. X    for (out = *make_list; out != NULL; out = out->next) {
  826. X        if (target(out->name,name) && out->use_it) {
  827. X            type = valid_source_file(out->name);
  828. X            fprintf(fp,"%s:\t",name);
  829. X            last = last_node(make_list,out->name);
  830. X            count = 0;
  831. X            for (in = *make_list; in != NULL; in = in->next) {
  832. X                if (valid_source_file(in->name) == CSOURCE &&
  833. X                    strcmp(in->name,out->name))
  834. X                    continue;
  835. X                if (in_file_list(in,out->name)) {
  836. X                    ++count;
  837. X                    if (strcmp(in->name,name))
  838. X                        write_dep(fp,count,in,last,in->name);
  839. X                    else
  840. X                        write_dep(fp,count,in,last,"");
  841. X                }
  842. X            }
  843. X            write_command(fp,out->name,type,opts);
  844. X        }
  845. X    }
  846. X    fclose(fp);
  847. X    return(1);
  848. X}
  849. X
  850. Xwrite_command(fp,name,type,opts)
  851. XFILE        *fp;
  852. Xchar        *name;
  853. Xint        type;
  854. XOPTS        *opts;
  855. X{
  856. X    switch (type) {
  857. X        case CSOURCE:    fprintf(fp,"\t\t$(CC) $(COPTS) -c %s\n\n",name);
  858. X                break;
  859. X        case CHEADER:    fprintf(fp,"\t\ttouch %s\n\n",name);
  860. X                break;
  861. X    }
  862. X}
  863. X
  864. Xwrite_dep(fp,count,in,last,name)
  865. XFILE        *fp;
  866. Xint        count;
  867. XDNODE        *in;
  868. XDNODE        *last;
  869. Xchar        *name;
  870. X{
  871. X    if (count == 1 && in != last)
  872. X        fprintf(fp,"%s\\\n",name);
  873. X    else if (count == 1)
  874. X        fprintf(fp,"%s\n",name);
  875. X    else if (in == last)
  876. X        fprintf(fp,"\t\t%s\n",name);
  877. X    else
  878. X        fprintf(fp,"\t\t%s\\\n",name);
  879. X}
  880. X
  881. XDNODE *
  882. Xlast_node(make_list,name)
  883. XDNODE        **make_list;
  884. Xchar        *name;
  885. X{
  886. X    DNODE        *last = NULL;
  887. X    DNODE        *in;
  888. X
  889. X    for (in = *make_list; in != NULL; in = in->next) {
  890. X        if (valid_source_file(in->name) == CSOURCE &&
  891. X            strcmp(in->name,name))
  892. X            continue;
  893. X        if (in_file_list(in,name))
  894. X            last = in;
  895. X    }
  896. X    return(last);
  897. X}    
  898. X
  899. Xmacros(make_list,fp,opts,mname)
  900. XDNODE        **make_list;
  901. XFILE        *fp;
  902. XOPTS        *opts;
  903. Xchar        *mname;
  904. X{
  905. X    fprintf(fp,"#%s\n",BANNER);
  906. X    fprintf(fp,"CC= cc\n");
  907. X    fprintf(fp,"COPTS= -g\n");
  908. X    fprintf(fp,"OFILES= \\\n");
  909. X    if (!ofiles(make_list,fp,opts))
  910. X        return(0);
  911. X    fprintf(fp,"#\n");
  912. X    if (!main_target(fp,opts,mname))
  913. X        return(0);
  914. X    return(1);
  915. X}
  916. X
  917. Xofiles(make_list,fp,opts)
  918. XDNODE        **make_list;
  919. XFILE        *fp;
  920. XOPTS        *opts;
  921. X{
  922. X    DNODE        *cur;
  923. X    DIR        *dirp;
  924. X    struct direct    *dp;
  925. X    int        type;
  926. X    char        name[BUFSIZE];
  927. X    char        last[BUFSIZE];
  928. X
  929. X    if ((dirp = opendir(".")) == NULL) {
  930. X        fprintf(stderr,"ofiles(): can't open directory\n");
  931. X        return(0);
  932. X    }
  933. X    if (!last_ofile(make_list,opts,last)) {
  934. X        closedir(dirp);
  935. X        return(0);    
  936. X    }
  937. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  938. X        type = valid_source_file(dp->d_name);
  939. X        if ((cur = find_dep(make_list,dp->d_name)) == NULL)
  940. X            continue;
  941. X        if (type == CSOURCE && target(dp->d_name,name) && cur->use_it)
  942. X            if (strcmp(last,dp->d_name))
  943. X                fprintf(fp,"\t%s\\\n",name);
  944. X            else
  945. X                fprintf(fp,"\t%s\n",name);
  946. X    }
  947. X    closedir(dirp);
  948. X    return(1);
  949. X}
  950. X
  951. Xlast_ofile(make_list,opts,last)
  952. XDNODE        **make_list;
  953. XOPTS        *opts;
  954. Xchar        *last;
  955. X{
  956. X    DNODE        *cur;
  957. X    DIR        *dirp;
  958. X    struct direct    *dp;
  959. X    int        type;
  960. X    char        name[BUFSIZE];
  961. X
  962. X    if ((dirp = opendir(".")) == NULL) {
  963. X        fprintf(stderr,"last_ofile(): can't open directory\n");
  964. X        return(0);
  965. X    }
  966. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  967. X        type = valid_source_file(dp->d_name);
  968. X        if ((cur = find_dep(make_list,dp->d_name)) == NULL)
  969. X            continue;
  970. X        if (type == CSOURCE && target(dp->d_name,name) && cur->use_it)
  971. X            strcpy(last,dp->d_name);
  972. X    }
  973. X    closedir(dirp);
  974. X    return(1);
  975. X}
  976. X
  977. Xfind_main_target(opts,mname)
  978. XOPTS        *opts;
  979. Xchar        *mname;
  980. X{
  981. X    DIR        *dirp;
  982. X    struct direct    *dp;
  983. X    int        type;
  984. X    int        count = 0;
  985. X
  986. X    if ((dirp = opendir(".")) == NULL) {
  987. X        fprintf(stderr,"main_target(): can't open directory\n");
  988. X        return(0);
  989. X    }
  990. X    mname[0] = NULL;    
  991. X    for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  992. X        type = valid_source_file(dp->d_name);
  993. X        if (type == CSOURCE)
  994. X            if (depends(dp->d_name,"main")) {
  995. X                if (++count > 1) 
  996. X                    fprintf(stderr,"Warning: main() multiply defined: %s\n",dp->d_name);
  997. X                strcpy(mname,dp->d_name);
  998. X            }
  999. X
  1000. X    }
  1001. X    closedir(dirp);
  1002. X    return(1);
  1003. X}
  1004. X
  1005. Xmain_target(fp,opts,mname)
  1006. XFILE        *fp;
  1007. XOPTS        *opts;
  1008. Xchar        *mname;
  1009. X{
  1010. X    int        i;
  1011. X    char        name[BUFSIZE];
  1012. X
  1013. X    strcpy(name,mname);
  1014. X    for (i = 0; name[i] != '.' && name[i] != NULL; i++)
  1015. X        ;
  1016. X    name[i] = NULL;    
  1017. X    fprintf(fp,"%s:\t$(OFILES)\n",name);
  1018. X    fprintf(fp,"\t\t$(CC) $(COPTS) -o %s $(OFILES)\n\n",name);
  1019. X    return(1);
  1020. X}
  1021. X
  1022. Xtarget(old,new)
  1023. Xchar        *old;
  1024. Xchar        *new;
  1025. X{
  1026. X    int        i;
  1027. X
  1028. X    strcpy(new,old);
  1029. X    for (i = 0; old[i] != '.' && old[i] != NULL; i++)
  1030. X        ;
  1031. X    if (old[i] == NULL)
  1032. X        return(0);
  1033. X    if (!strcmp(&old[i+1],"c"))
  1034. X        new[i+1] = 'o';
  1035. X    else if (!strcmp(&old[i+1],"h"))
  1036. X        ;
  1037. X    else
  1038. X        return(0);
  1039. X    return(1);
  1040. X}
  1041. END-of-makef.c
  1042. echo x - nodes.c
  1043. sed 's/^X//' >nodes.c << 'END-of-nodes.c'
  1044. X/* nodes.c */
  1045. X
  1046. X#include <stdio.h>
  1047. X#include "types.h"
  1048. X
  1049. XDNODE *
  1050. Xadd_dep_node(make_list,name)
  1051. XDNODE        **make_list;
  1052. Xchar        *name;
  1053. X{
  1054. X    DNODE        *prev;
  1055. X    DNODE        *cur;
  1056. X    DNODE        *new;
  1057. X
  1058. X    for (prev = NULL, cur = *make_list; cur != NULL; cur = cur->next)
  1059. X        prev = cur;
  1060. X    new = (DNODE *)malloc(sizeof(DNODE));
  1061. X    new->name = (char *)malloc(strlen(name)+1);
  1062. X    strcpy(new->name,name);
  1063. X    new->next = NULL;
  1064. X    new->dlist = NULL;
  1065. X    new->use_it = 1;
  1066. X    if (prev == NULL)
  1067. X        *make_list = new;
  1068. X    else
  1069. X        prev->next = new;
  1070. X    return(new);
  1071. X}
  1072. X
  1073. XFNODE *
  1074. Xadd_file_node(dnode,name)
  1075. XDNODE        *dnode;
  1076. Xchar        *name;
  1077. X{
  1078. X    FNODE        *prev;
  1079. X    FNODE        *cur;
  1080. X    FNODE        *new;
  1081. X
  1082. X    for (prev = NULL, cur = dnode->dlist; cur != NULL; cur = cur->next)
  1083. X        prev = cur;
  1084. X    new = (FNODE *)malloc(sizeof(FNODE));
  1085. X    new->name = (char *)malloc(strlen(name)+1);
  1086. X    strcpy(new->name,name);
  1087. X    new->next = NULL;
  1088. X    if (prev == NULL)
  1089. X        dnode->dlist = new;
  1090. X    else
  1091. X        prev->next = new;
  1092. X    return(new);
  1093. X}
  1094. X
  1095. Xin_file_list(dnode,name)
  1096. XDNODE        *dnode;
  1097. Xchar        *name;
  1098. X{
  1099. X    FNODE        *cur;
  1100. X
  1101. X    for (cur = dnode->dlist; cur != NULL; cur = cur->next)
  1102. X        if (!strcmp(cur->name,name))
  1103. X            return(1);
  1104. X    return(0);
  1105. X}
  1106. X
  1107. XDNODE *
  1108. Xfind_dep(make_list,name)
  1109. XDNODE        **make_list;
  1110. Xchar        *name;
  1111. X{
  1112. X    DNODE        *cur;
  1113. X
  1114. X    for (cur = *make_list; cur != NULL; cur = cur->next)
  1115. X        if (!strcmp(cur->name,name))
  1116. X            return(cur);
  1117. X    return(NULL);
  1118. X}
  1119. X
  1120. Xfree_list(make_list)
  1121. XDNODE        **make_list;
  1122. X{
  1123. X    DNODE        *cur;
  1124. X    DNODE        *next;
  1125. X
  1126. X    cur = *make_list;
  1127. X    while (cur != NULL) {
  1128. X        next = cur->next;
  1129. X        free(cur->name);
  1130. X        free_fnodes(cur->dlist);
  1131. X        free(cur);
  1132. X        cur = next;
  1133. X    }
  1134. X}
  1135. X
  1136. Xfree_fnodes(dlist)
  1137. XFNODE        *dlist;
  1138. X{
  1139. X    FNODE        *next;
  1140. X
  1141. X    while (dlist != NULL) {
  1142. X        next = dlist->next;
  1143. X        free(dlist->name);
  1144. X        free(dlist);
  1145. X        dlist = next;
  1146. X    }
  1147. X}
  1148. END-of-nodes.c
  1149. echo x - parse.c
  1150. sed 's/^X//' >parse.c << 'END-of-parse.c'
  1151. X/* parse.c */
  1152. X
  1153. X#include <stdio.h>
  1154. X#include "types.h"
  1155. X
  1156. Xint    sp;
  1157. X
  1158. Xparse_file(fp,fname,count,buf,curp,cpp_stack,symtab)
  1159. XFILE        *fp;
  1160. Xchar        *fname;
  1161. Xint        *count;
  1162. Xchar        *buf;
  1163. Xint        *curp;
  1164. XCPPN        **cpp_stack;
  1165. XSYMENT        **symtab;
  1166. X{
  1167. X    int    not_empty;
  1168. X    int    lb_count = *count;
  1169. X    char    tok[BUFSIZE];
  1170. X    int    cp = *curp;
  1171. X
  1172. X    while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
  1173. X        if (tok[0] == '{') {
  1174. X            ++lb_count;
  1175. X        } else if (tok[0] == '}') {
  1176. X            --lb_count;
  1177. X        } else {
  1178. X            if (lb_count > 0)
  1179. X                continue;
  1180. X            /* possible function definition, 1st ed K&R */
  1181. X            strcpy(fname,tok);
  1182. X            if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
  1183. X                return(0);
  1184. X            if (tok[0] != '(') {
  1185. X                cp = sp;
  1186. X                continue;
  1187. X            }
  1188. X            not_empty = 0;
  1189. X            while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0 && tok[0] != ')') {
  1190. X                not_empty = 1;
  1191. X                if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
  1192. X                    return(0);
  1193. X                if (tok[0] == ')')
  1194. X                    break;
  1195. X            }
  1196. X            if (cp < 0)
  1197. X                return(0);
  1198. X            if (!not_empty) {
  1199. X                if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0)
  1200. X                    return(0);
  1201. X                if (tok[0] != '{')
  1202. X                    continue;
  1203. X                ++lb_count;
  1204. X            }
  1205. X            *curp = cp;
  1206. X            *count = lb_count;
  1207. X            return(1);
  1208. X        }
  1209. X    }
  1210. X    return(0);
  1211. X}
  1212. X
  1213. X
  1214. Xdepends(filename,funcname)
  1215. Xchar        *filename;
  1216. Xchar        *funcname;
  1217. X{
  1218. X    FILE        *fp;
  1219. X    char        tok[BUFSIZE];
  1220. X    char        buf[BUFSIZE];
  1221. X    char        cur_func[BUFSIZE];
  1222. X    int        cp = 0;
  1223. X    CPPN        **cpp_stack;
  1224. X    SYMENT        **symtab;
  1225. X
  1226. X    cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
  1227. X    *cpp_stack = NULL;
  1228. X    symtab = (SYMENT **)malloc(sizeof(SYMENT *));
  1229. X    *symtab = NULL;
  1230. X    if ((fp = fopen(filename,"r")) == NULL) {
  1231. X        fprintf(stderr,"depends():  can't open file %s\n",filename);
  1232. X        cpp_rel(cpp_stack,symtab);
  1233. X        return(0);
  1234. X    }
  1235. X    cur_func[BUFSIZE] = NULL;
  1236. X    buf[0] = NULL;
  1237. X    while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
  1238. X        if (!strcmp(tok,funcname)) {
  1239. X            if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
  1240. X                fclose(fp);
  1241. X                cpp_rel(cpp_stack,symtab);
  1242. X                return(0);
  1243. X            }
  1244. X            if (tok[0] == '(') {
  1245. X                fclose(fp);
  1246. X                cpp_rel(cpp_stack,symtab);
  1247. X                return(1);
  1248. X            }
  1249. X            cp = sp;
  1250. X        }
  1251. X    }
  1252. X    fclose(fp);
  1253. X    cpp_rel(cpp_stack,symtab);
  1254. X    return(0);
  1255. X}
  1256. X
  1257. Xhdepends(filename,sname)
  1258. Xchar        *filename;
  1259. Xchar        *sname;
  1260. X{
  1261. X    FILE        *fp;
  1262. X    char        tok[BUFSIZE];
  1263. X    char        buf[BUFSIZE];
  1264. X    char        name[BUFSIZE];
  1265. X    int        cp = 0;
  1266. X    CPPN        **cpp_stack;
  1267. X    SYMENT        **symtab;
  1268. X
  1269. X    cpp_stack = (CPPN **)malloc(sizeof(CPPN *));
  1270. X    *cpp_stack = NULL;
  1271. X    symtab = (SYMENT **)malloc(sizeof(SYMENT *));
  1272. X    *symtab = NULL;
  1273. X    if ((fp = fopen(filename,"r")) == NULL) {
  1274. X        fprintf(stderr,"depends():  can't open file %s\n",filename);
  1275. X        return(0);
  1276. X    }
  1277. X    strcpy(name,"\"");
  1278. X    strcat(name,sname);
  1279. X    strcat(name,"\"");
  1280. X    buf[0] = NULL;
  1281. X    while ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) >= 0) {
  1282. X        if (tok[0] == '#' && sp == 0) {
  1283. X            if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
  1284. X                fclose(fp);
  1285. X                return(0);
  1286. X            }
  1287. X            if (!strcmp("include",tok)) {
  1288. X                if ((cp = gettok(fp,buf,tok,cp,cpp_stack,symtab)) < 0) {
  1289. X                    fclose(fp);
  1290. X                    return(0);
  1291. X                }
  1292. X                if (!strcmp(name,tok)) {
  1293. X                    fclose(fp);
  1294. X                    return(1);
  1295. X                }
  1296. X            }
  1297. X        }
  1298. X    }
  1299. X    fclose(fp);
  1300. X    return(0);
  1301. X}
  1302. X
  1303. Xgettok(fp,buf,curtok,cp,cpp_stack,symtab)
  1304. XFILE        *fp;
  1305. Xchar        *buf;
  1306. Xchar        *curtok;
  1307. Xint        cp;
  1308. XCPPN        **cpp_stack;
  1309. XSYMENT        **symtab;
  1310. X{
  1311. X    int        quote = 0;
  1312. X    int        tokind = 0;
  1313. X    int        in_comment = 0;
  1314. X    char        quotechar;
  1315. X
  1316. X    do {
  1317. X#ifdef DEBUG
  1318. X        printf("eating whitespace\n");
  1319. X#endif
  1320. X        while (is_white(buf[cp]))
  1321. X            ++cp;
  1322. X#ifdef DEBUG
  1323. X        printf("cp = %4d  buf[cp] = '%c'\n",cp,buf[cp]);
  1324. X#endif
  1325. X        if (buf[cp] == NULL && fp != NULL) {
  1326. X            if (fgets(buf,BUFSIZE-1,fp) == NULL)
  1327. X                return(-1);
  1328. X            if (!in_comment) {
  1329. X                if (cpp_parse(buf,cpp_stack,symtab) < 0)
  1330. X                    return(-1);
  1331. X                if (cpp_stack != NULL) {
  1332. X                    if (!cpp_useline(cpp_stack,symtab)) {
  1333. X                        buf[0] = ' ';
  1334. X                        buf[1] = NULL;
  1335. X                    }    
  1336. X                }
  1337. X            }
  1338. X            cp = 0;
  1339. X        }
  1340. X        else if (buf[cp] == NULL) {
  1341. X            curtok[0] = NULL;
  1342. X            return(-1);
  1343. X        }    
  1344. X        if (!in_comment) {
  1345. X            if (buf[cp] == '/' && buf[cp+1] == '*') {
  1346. X                in_comment = 1;
  1347. X                cp += 2;
  1348. X            }
  1349. X        }
  1350. X        else {
  1351. X            if (buf[cp] == '*' && buf[cp+1] == '/') {
  1352. X                in_comment = 0;
  1353. X                cp += 2;
  1354. X            }
  1355. X            else 
  1356. X                cp++;
  1357. X        }
  1358. X#ifdef DEBUG
  1359. X        printf("in_comment = %d\n",in_comment);
  1360. X#endif
  1361. X    } while (is_white(buf[cp]) || in_comment);
  1362. X    sp = cp;
  1363. X    if (is_quote(buf[cp])) {
  1364. X        quotechar = buf[cp++];
  1365. X        curtok[tokind++] = quotechar;
  1366. X        quote = 1;
  1367. X    }
  1368. X    if ((is_tok_sep(buf[cp]) || buf[cp] == NULL) && quote == 0) {
  1369. X        curtok[tokind++] = buf[cp++];
  1370. X        if (curtok[tokind-1] == '<' && (buf[cp] == '>' ||
  1371. X            buf[cp] == '=')) {
  1372. X            curtok[tokind++] = buf[cp++];
  1373. X        } else if (curtok[tokind-1] == '>' && buf[cp] == '=') {
  1374. X            curtok[tokind++] = buf[cp++];
  1375. X        }
  1376. X    }
  1377. X    else {
  1378. X        while ((!is_tok_sep(buf[cp]) && !is_white(buf[cp]) &&
  1379. X             buf[cp] != NULL && quote == 0) ||
  1380. X            (buf[cp] != NULL && quote == 1)) {
  1381. X            if (quote == 1 && buf[cp] == '\\')
  1382. X                ++cp;
  1383. X            else if (quote == 1 && buf[cp] == quotechar)
  1384. X                break;
  1385. X            curtok[tokind++] = buf[cp++];
  1386. X        }
  1387. X    }
  1388. X    if (quote == 1) {
  1389. X        curtok[tokind++] = buf[cp++];
  1390. X    }
  1391. X    curtok[tokind] = NULL;
  1392. X    return(cp);
  1393. X}
  1394. X
  1395. Xis_white(c)
  1396. Xchar        c;
  1397. X{
  1398. X    return((c == '\t' || c == '\n' || c == ' '));
  1399. X}
  1400. X
  1401. Xis_quote(c)
  1402. Xchar        c;
  1403. X{
  1404. X    return((c == '\'' || c == '\"'));
  1405. X}
  1406. X
  1407. Xis_tok_sep(c)
  1408. Xchar        c;
  1409. X{
  1410. X    return((c == ',' || c == '(' ||
  1411. X        c == '#' || c == '!' ||
  1412. X        c == '-' || c == '+' ||
  1413. X        c == '*' || c == '/' ||
  1414. X        c == '>' || c == '<' ||
  1415. X        c == '=' || c == ';' ||
  1416. X        c == ';' || c == ')' ||
  1417. X        c == '[' || c == ']' ||
  1418. X        c == ':' || c == '\\' ||
  1419. X        c == '[' || c == ']'));
  1420. X}
  1421. X
  1422. END-of-parse.c
  1423. echo x - print_deps.c
  1424. sed 's/^X//' >print_deps.c << 'END-of-print_deps.c'
  1425. X#include <stdio.h>
  1426. X#include "types.h"
  1427. X
  1428. Xprint_deps(make_list)
  1429. XDNODE        **make_list;
  1430. X{
  1431. X    DNODE        *dcur;
  1432. X    FNODE        *fcur;
  1433. X
  1434. X    for (dcur = *make_list; dcur != NULL; dcur = dcur->next) {
  1435. X        printf("\nThese files:\n");
  1436. X        for (fcur = dcur->dlist; fcur != NULL; fcur = fcur->next)
  1437. X            printf("\t%s\n",fcur->name);
  1438. X        printf("Depend on this file: %s\n",dcur->name);
  1439. X    }
  1440. X}
  1441. END-of-print_deps.c
  1442. echo x - valid.c
  1443. sed 's/^X//' >valid.c << 'END-of-valid.c'
  1444. X/* valid.c */
  1445. X
  1446. X#include <stdio.h>
  1447. X#include "types.h"
  1448. X
  1449. Xvalid_source_file(name)
  1450. Xchar        *name;
  1451. X{
  1452. X    int        i;
  1453. X
  1454. X    for (i = 0; name[i] != NULL && name[i] != '.'; i++)
  1455. X        ;
  1456. X    if (name[i] == '.') {
  1457. X        if (!strcmp(&name[i+1],"c"))
  1458. X            return(CSOURCE);
  1459. X        if (!strcmp(&name[i+1],"h"))
  1460. X            return(CHEADER);
  1461. X    }
  1462. X    return(0);
  1463. X}
  1464. X
  1465. END-of-valid.c
  1466. exit
  1467.  
  1468.  
  1469. exit 0 # Just in case...
  1470. -- 
  1471. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1472. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1473. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1474. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1475.